package global

import (
	"fmt"
	"sync"
	"time"

	"baseService/internal/infrastructure/config"
	"baseService/internal/infrastructure/persistence"
	"baseService/internal/pkg/cache"
	"baseService/internal/pkg/eventbus"
	"baseService/internal/pkg/logger"
	"baseService/internal/pkg/validator"

	"gorm.io/gorm"
)

// 全局变量 - 简单直接，方便使用
var (
	// Config 核心组件
	Config   *config.Config     // 配置
	DB       *gorm.DB           // 数据库
	Logger   logger.Logger      // 日志
	Cache    cache.Cache        // 缓存
	EventBus *eventbus.EventBus // 事件总线（指向 eventbus.DefaultBus）

	// ConfigManager 管理器（需要时使用）
	ConfigManager *config.ConfigManager
	DBManager     *persistence.DatabaseManager

	// IsProduction 快捷访问
	IsProduction  bool // 是否生产环境
	IsDevelopment bool // 是否开发环境

	// 确保只初始化一次
	once    sync.Once
	initErr error
)

// Init 初始化所有全局组件 - 一次调用，全局可用
func Init(configPath string) error {
	once.Do(func() {
		initErr = doInit(configPath)
	})
	return initErr
}

// doInit 实际的初始化逻辑
func doInit(configPath string) error {
	// 1. 配置 - 最高优先级
	if err := initConfig(configPath); err != nil {
		return fmt.Errorf("初始化配置失败: %w", err)
	}

	// 2. 日志 - 第二优先级
	if err := initLogger(); err != nil {
		return fmt.Errorf("初始化日志失败: %w", err)
	}

	// 3. 验证器 - 无依赖
	if err := initValidator(); err != nil {
		return fmt.Errorf("初始化验证器失败: %w", err)
	}

	// 4. 缓存 - 依赖日志
	if err := initCache(); err != nil {
		return fmt.Errorf("初始化缓存失败: %w", err)
	}

	// 5. 数据库 - 依赖配置和日志
	if err := initDatabase(); err != nil {
		return fmt.Errorf("初始化数据库失败: %w", err)
	}

	// 6. 事件总线 - 使用全局 DefaultBus
	EventBus = eventbus.DefaultBus

	Logger.Info("全局组件初始化成功")
	return nil
}

// initConfig 初始化配置
func initConfig(configPath string) error {
	var err error
	ConfigManager, err = config.NewConfigManager(configPath)
	if err != nil {
		return err
	}

	Config = ConfigManager.GetConfig()

	// 设置快捷访问变量
	IsProduction = Config.IsProduction()
	IsDevelopment = Config.IsDevelopment()

	return nil
}

// initLogger 初始化日志
func initLogger() error {
	var err error

	// 使用配置文件的日志配置
	logConfigMap := map[string]interface{}{
		"filename":    Config.Log.Filename,
		"max_size":    Config.Log.MaxSize,
		"max_age":     Config.Log.MaxAge,
		"max_backups": Config.Log.MaxBackups,
		"compress":    Config.Log.Compress,
		"local_time":  Config.Log.LocalTime,
	}

	Logger, err = logger.NewEnvironmentLoggerWithConfig(Config.App.Environment, logConfigMap)
	if err != nil {
		return err
	}

	// 设置全局日志实例
	logger.SetGlobalLogger(Logger)

	Logger.Info("日志系统初始化成功")
	return nil
}

// initValidator 初始化验证器
func initValidator() error {
	locale := "zh"
	if Config.App.Locale != "" {
		locale = Config.App.Locale
	}

	if err := validator.Init(locale); err != nil {
		return err
	}

	Logger.Info("验证器初始化成功")
	return nil
}

// initCache 初始化缓存
func initCache() error {
	// 从配置文件构建缓存配置
	cfg := &cache.CacheConfig{
		Engine:          Config.Cache.Engine,
		DefaultTTL:      parseDurationOrDefault(Config.Cache.DefaultTTL, 30*time.Minute),
		RedisURL:        Config.Cache.Redis.URL,
		RedisPrefix:     Config.Cache.Redis.Prefix,
		MaxItems:        Config.Cache.Memory.MaxItems,
		CleanupInterval: parseDurationOrDefault(Config.Cache.Memory.CleanupInterval, 5*time.Minute),
	}

	var err error
	Cache, err = cache.NewCacheWithConfig(cfg, Logger)
	if err != nil {
		return err
	}

	Logger.Infof("缓存系统初始化成功 - engine: %s, ttl: %s", cfg.Engine, cfg.DefaultTTL)
	return nil
}

// parseDurationOrDefault 解析时间字符串
func parseDurationOrDefault(s string, defaultValue time.Duration) time.Duration {
	if d, err := time.ParseDuration(s); err == nil {
		return d
	}
	return defaultValue
}

// initDatabase 初始化数据库
func initDatabase() error {
	DBManager = persistence.NewDatabaseManager(Config, Logger)

	if err := DBManager.Initialize(); err != nil {
		return err
	}

	DB = DBManager.GetDB()

	// 执行数据库迁移
	if Config.Database.AutoMigrate {
		Logger.Info("开始执行数据库自动迁移...")
		if err := DBManager.Migrate(); err != nil {
			return fmt.Errorf("数据库迁移失败: %w", err)
		}
		Logger.Info("数据库迁移完成")
	}

	Logger.Info("数据库系统初始化成功")
	return nil
}

// Close 关闭所有全局资源
func Close() error {
	if Logger != nil {
		Logger.Info("开始关闭全局资源")
	}

	// EventBus 无需关闭（goroutine 会自然结束）

	// 关闭缓存
	if Cache != nil {
		if err := Cache.Close(); err != nil && Logger != nil {
			Logger.Errorf("缓存关闭失败: %v", err)
		}
	}

	// 关闭数据库
	if DBManager != nil {
		if err := DBManager.Close(); err != nil && Logger != nil {
			Logger.Errorf("数据库连接关闭失败: %v", err)
		}
	}

	if Logger != nil {
		Logger.Info("全局资源关闭完成")
	}

	return nil
}

// MustInit 确保已初始化，否则panic
func MustInit() {
	if Config == nil || DB == nil || Logger == nil {
		panic("全局组件未初始化，请先调用 g.Init()")
	}
}

// IsInitialized 检查是否已初始化
func IsInitialized() bool {
	return Config != nil && DB != nil && Logger != nil && Cache != nil
}

// GetConnectionStats 获取数据库连接池统计信息
func GetConnectionStats() (map[string]interface{}, error) {
	if DBManager == nil {
		return nil, fmt.Errorf("数据库管理器未初始化")
	}
	return DBManager.GetConnectionStats()
}
